// internal/parser/parser/select.go
package parser

import (
	"fmt"
	"strconv"

	"NumberBase/internal/parser/ast"
	"NumberBase/internal/parser/lexer"
)

// parseSelectStatement 解析SELECT语句
// 例如: SELECT id, name FROM users WHERE age > 18
func (p *Parser) parseSelectStatement() (*ast.SelectStatement, error) {
	stmt := &ast.SelectStatement{
		JoinClauses: []ast.JoinClause{}, // 初始化为空切片
	}

	// 跳过SELECT关键字
	p.nextToken()

	// 解析列名列表
	columns, err := p.parseExpressionList(lexer.COMMA)
	if err != nil {
		return nil, err
	}
	stmt.Columns = columns

	// 当前token应该是列表中最后一个表达式，需要前进到FROM
	p.nextToken()

	// 期望当前Token是FROM
	if !p.currTokenIs(lexer.FROM) {
		return nil, fmt.Errorf("期望FROM，但得到%s", p.currToken.Literal)
	}

	// 解析表名或子查询
	p.nextToken()
	if p.currTokenIs(lexer.LPAREN) {
		// 这是一个子查询
		subquery, err := p.parseSubquery()
		if err != nil {
			return nil, err
		}
		stmt.Subquery = subquery
		// TableName 保持为空，因为我们现在使用子查询

		// 检查子查询后面是否有别名（必须有AS关键字）
		if p.currTokenIs(lexer.AS) {
			p.nextToken() // 跳过AS
			if !p.currTokenIs(lexer.IDENTIFIER) {
				return nil, fmt.Errorf("期望子查询别名，但得到%s", p.currToken.Literal)
			}
			stmt.TableAlias = p.currToken.Literal
			p.nextToken() // 跳过别名
		}
	} else if p.currTokenIs(lexer.IDENTIFIER) {
		// 这是一个普通表名
		stmt.TableName = p.currToken.Literal

		// 检查是否有表别名
		p.nextToken()
		if p.currTokenIs(lexer.AS) {
			p.nextToken() // 跳过AS
			if !p.currTokenIs(lexer.IDENTIFIER) {
				return nil, fmt.Errorf("期望表别名，但得到%s", p.currToken.Literal)
			}
			stmt.TableAlias = p.currToken.Literal
			p.nextToken() // 跳过别名
		} else if p.currTokenIs(lexer.IDENTIFIER) {
			// 隐式别名
			stmt.TableAlias = p.currToken.Literal
			p.nextToken() // 跳过别名
		}
	} else {
		return nil, fmt.Errorf("期望表名或子查询，但得到%s", p.currToken.Literal)
	}

	// 解析JOIN子句(可选)
	for p.currTokenIs(lexer.INNER) || p.currTokenIs(lexer.LEFT) || p.currTokenIs(lexer.RIGHT) || p.currTokenIs(lexer.FULL) || p.currTokenIs(lexer.JOIN) {
		joinClause, err := p.parseJoinClause()
		if err != nil {
			return nil, err
		}
		stmt.JoinClauses = append(stmt.JoinClauses, *joinClause)
		// parseJoinClause 会自动前进到下一个token
	}

	// 解析WHERE子句(可选)
	if p.currTokenIs(lexer.WHERE) {
		p.nextToken() // 跳过WHERE关键字
		where, err := p.parseExpression(LOWEST)
		if err != nil {
			return nil, err
		}
		stmt.Where = where

		p.nextToken()
	}

	// 解析ORDER BY子句(可选)
	if p.currTokenIs(lexer.ORDER) {
		orderBy, err := p.parseOrderByClause()
		if err != nil {
			return nil, err
		}
		stmt.OrderBy = orderBy
	}

	// 解析LIMIT子句(可选)
	if p.currTokenIs(lexer.LIMIT) {
		limit, err := p.parseLimitClause()
		if err != nil {
			return nil, err
		}
		stmt.Limit = limit
	}

	// 检查下一个token是否是分号(作为SQL语句结束标记)
	if p.peekTokenIs(lexer.SEMICOLON) {
		p.nextToken() // 消费分号，确认语句结束
	}
	// 如果没有分号，也允许语句结束（某些SQL环境中分号是可选的）

	return stmt, nil
}

// parseJoinClause 解析JOIN子句
// 例如: INNER JOIN orders ON users.id = orders.user_id
func (p *Parser) parseJoinClause() (*ast.JoinClause, error) {
	join := &ast.JoinClause{}

	// 确定连接类型
	if p.currTokenIs(lexer.INNER) {
		join.JoinType = ast.INNER
		// 跳过JOIN关键字
		if !p.expectPeek(lexer.JOIN) {
			return nil, fmt.Errorf("期望JOIN，但得到%s", p.peekToken.Literal)
		}
	} else if p.currTokenIs(lexer.LEFT) {
		join.JoinType = ast.LEFT
		// 跳过JOIN关键字
		if !p.expectPeek(lexer.JOIN) {
			return nil, fmt.Errorf("期望JOIN，但得到%s", p.peekToken.Literal)
		}
	} else if p.currTokenIs(lexer.RIGHT) {
		join.JoinType = ast.RIGHT
		// 跳过JOIN关键字
		if !p.expectPeek(lexer.JOIN) {
			return nil, fmt.Errorf("期望JOIN，但得到%s", p.peekToken.Literal)
		}
	} else if p.currTokenIs(lexer.FULL) {
		join.JoinType = ast.FULL
		// 跳过JOIN关键字
		if !p.expectPeek(lexer.JOIN) {
			return nil, fmt.Errorf("期望JOIN，但得到%s", p.peekToken.Literal)
		}
	} else if p.currTokenIs(lexer.JOIN) {
		// 默认为INNER JOIN
		join.JoinType = ast.INNER
	} else {
		return nil, fmt.Errorf("不支持的JOIN类型: %s", p.currToken.Literal)
	}

	// 解析表名
	p.nextToken()
	if !p.currTokenIs(lexer.IDENTIFIER) {
		return nil, fmt.Errorf("期望表名，但得到%s", p.currToken.Literal)
	}
	join.TableName = p.currToken.Literal

	// 解析表别名(可选)
	p.nextToken()
	if p.currTokenIs(lexer.AS) {
		p.nextToken()
		if !p.currTokenIs(lexer.IDENTIFIER) {
			return nil, fmt.Errorf("期望表别名，但得到%s", p.currToken.Literal)
		}
		join.Alias = p.currToken.Literal
		p.nextToken()
	} else if p.currTokenIs(lexer.IDENTIFIER) {
		// 支持不带AS的别名语法: INNER JOIN orders o
		join.Alias = p.currToken.Literal
		p.nextToken()
	}

	// 期望下一个Token是ON
	if !p.currTokenIs(lexer.ON) {
		return nil, fmt.Errorf("期望ON，但得到%s", p.currToken.Literal)
	}

	// 解析ON子句的表达式
	p.nextToken()

	// 解析左表限定列名
	if !p.currTokenIs(lexer.IDENTIFIER) {
		return nil, fmt.Errorf("期望左表名，但得到%s", p.currToken.Literal)
	}
	join.Condition.LeftTable = p.currToken.Literal

	// 期望下一个Token是点号
	if !p.expectPeek(lexer.DOT) {
		return nil, fmt.Errorf("期望.，但得到%s", p.peekToken.Literal)
	}

	// 解析左表列名
	p.nextToken()
	if !p.currTokenIs(lexer.IDENTIFIER) {
		return nil, fmt.Errorf("期望左表列名，但得到%s", p.currToken.Literal)
	}
	join.Condition.LeftColumn = p.currToken.Literal

	// 期望下一个Token是等号
	if !p.expectPeek(lexer.EQUAL) {
		return nil, fmt.Errorf("期望=，但得到%s", p.peekToken.Literal)
	}

	// 解析右表限定列名
	p.nextToken()
	if !p.currTokenIs(lexer.IDENTIFIER) {
		return nil, fmt.Errorf("期望右表名，但得到%s", p.currToken.Literal)
	}
	join.Condition.RightTable = p.currToken.Literal

	// 期望下一个Token是点号
	if !p.expectPeek(lexer.DOT) {
		return nil, fmt.Errorf("期望.，但得到%s", p.peekToken.Literal)
	}

	// 解析右表列名
	p.nextToken()
	if !p.currTokenIs(lexer.IDENTIFIER) {
		return nil, fmt.Errorf("期望右表列名，但得到%s", p.currToken.Literal)
	}
	join.Condition.RightColumn = p.currToken.Literal

	// 移动到下一个 token，为后续处理其他 JOIN 或 WHERE 等条件做准备
	p.nextToken()

	return join, nil
}

// parseOrderByClause 解析ORDER BY子句
// 例如: ORDER BY id, name DESC
func (p *Parser) parseOrderByClause() ([]ast.OrderByClause, error) {
	clauses := []ast.OrderByClause{}

	// 跳过ORDER关键字
	p.nextToken()

	// 期望下一个Token是BY
	if !p.currTokenIs(lexer.BY) {
		return nil, fmt.Errorf("期望BY，但得到%s", p.currToken.Literal)
	}

	// 跳过BY关键字
	p.nextToken()

	// 解析第一个排序项
	clause, err := p.parseOrderByItem()
	if err != nil {
		return nil, err
	}
	clauses = append(clauses, clause)

	// 解析额外的排序项(如果有)
	for p.peekTokenIs(lexer.COMMA) {
		p.nextToken() // 跳过逗号
		p.nextToken() // 移动到下一个排序项

		clause, err := p.parseOrderByItem()
		if err != nil {
			return nil, err
		}
		clauses = append(clauses, clause)
	}

	// 移动到ORDER BY之后的下一个token
	p.nextToken()

	return clauses, nil
}

// parseOrderByItem 解析ORDER BY子句中的单个项
// 例如: id ASC 或 name DESC
func (p *Parser) parseOrderByItem() (ast.OrderByClause, error) {
	// 解析列名
	if !p.currTokenIs(lexer.IDENTIFIER) {
		return ast.OrderByClause{}, fmt.Errorf("期望列名，但得到%s", p.currToken.Literal)
	}

	column := &ast.Identifier{Value: p.currToken.Literal}

	// 默认为升序(ASC)
	isDesc := false

	// 检查是否指定了排序方向
	if p.peekTokenIs(lexer.DESC) {
		p.nextToken() // 移动到DESC关键字
		isDesc = true
	} else if p.peekTokenIs(lexer.ASC) {
		p.nextToken() // 移动到ASC关键字
		// ASC是默认的，所以这里不需要更改isDesc
	}

	return ast.OrderByClause{
		Column: column,
		Desc:   isDesc,
	}, nil
}

// parseLimitClause 解析LIMIT子句
// 例如: LIMIT 10 或 LIMIT 5, 10
func (p *Parser) parseLimitClause() (*ast.LimitClause, error) {
	// 跳过LIMIT关键字
	p.nextToken()

	// 解析LIMIT值(offset或count)
	if !p.currTokenIs(lexer.NUMBER) {
		return nil, fmt.Errorf("期望数字，但得到%s", p.currToken.Literal)
	}

	// 解析第一个数字
	firstNum, err := strconv.Atoi(p.currToken.Literal)
	if err != nil {
		return nil, fmt.Errorf("无法解析LIMIT值: %s", p.currToken.Literal)
	}

	// 默认情况下，第一个数字是count，offset为0
	offset := 0
	count := firstNum

	// 检查是否有 LIMIT offset, count 的形式
	if p.peekTokenIs(lexer.COMMA) {
		p.nextToken() // 跳过逗号
		p.nextToken() // 移动到第二个数字

		if !p.currTokenIs(lexer.NUMBER) {
			return nil, fmt.Errorf("期望数字，但得到%s", p.currToken.Literal)
		}

		// 如果有逗号，则第一个数字是offset，第二个数字是count
		secondNum, err := strconv.Atoi(p.currToken.Literal)
		if err != nil {
			return nil, fmt.Errorf("无法解析LIMIT值: %s", p.currToken.Literal)
		}

		offset = firstNum
		count = secondNum
	}

	// 移动到LIMIT之后的下一个token
	p.nextToken()

	return &ast.LimitClause{
		Offset: offset,
		Count:  count,
	}, nil
}

// parseSubquery 解析子查询
func (p *Parser) parseSubquery() (*ast.SubqueryExpression, error) {
	// 跳过左括号
	p.nextToken()

	if !p.currTokenIs(lexer.SELECT) {
		return nil, fmt.Errorf("子查询必须以SELECT开始，但得到%s", p.currToken.Literal)
	}

	// 解析内部SELECT语句
	subQuery, err := p.parseSelectStatement()
	if err != nil {
		return nil, err
	}

	// 当前token应该是右括号
	if !p.currTokenIs(lexer.RPAREN) {
		return nil, fmt.Errorf("期望右括号')'，但得到%s", p.currToken.Literal)
	}

	// 前进到右括号之后的token
	p.nextToken()

	return &ast.SubqueryExpression{Query: subQuery}, nil
}
